package model

import (
	"fmt"
	jsoniter "github.com/json-iterator/go"
	"gowork/shoppingCart/utils"
	"strconv"
	"time"
)

type User struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	CouponList []*Coupon `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Coupon struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	Deduction float64
	CreatedAt time.Time
	UpdatedAt time.Time
}

type UserCoupon struct {
	Id int64 `xorm:"pk autoincr"`
	UserId int64
	CouponId  int64
	Use bool
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Commodity struct {
	Id int64 `xorm:"pk autoincr"`
	Type int64
	TypeName string
	Name string
	Money float64
	CreatedAt time.Time
	UpdatedAt time.Time
}

type CommodityTypeCart struct {
	Type int64
	Name string
	CommodityCartList []*CommodityCart
}

type CommodityCart struct {
	Commodity *Commodity
	Number int
}

type UserCommodity struct {
	Id int64 `xorm:"pk autoincr"`
	UserId int64
	CommodityId int64
	CommodityName string
	Number int
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (commodity *Commodity)CollectCoupons(c *Coupon, uId int64)(){

	w := new(utils.Worker)

	var uc = UserCoupon{
		Id:        w.GetId(),
		UserId:    uId,
		CouponId:  c.Id,
		Use:       false,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}
	x.Insert(&uc)
}

func (commodity *Commodity)QueryCoupons(uId int64)([]*Coupon, error){

	var cList []*Coupon
	x.Join("INNER", "user_coupon", "user_coupon.coupon_id = coupon.id").Where("user_coupon.user_id = ?", uId).And("user_coupon.use = ?", false).Find(&cList)

	return cList, nil
}

func (commodity *Commodity)AddShoppingCart(cList []*Commodity, uId int64)([]*CommodityTypeCart, error){

	var commodityTypeList []*CommodityTypeCart

	for _, c := range cList {
		var exist bool = false
		for _, t := range commodityTypeList {
			if t.Type == c.Type {
				exist = true
				var tem bool = false
				for _, commodity := range t.CommodityCartList {
					if commodity.Commodity.Id == c.Id {
						commodity.Number += 1
						tem = true
					}
				}

				if tem == false {
					var cc = CommodityCart{
						Commodity: c,
						Number:    1,
					}

					t.CommodityCartList = append(t.CommodityCartList, &cc)
				}
			}
		}
		if exist == false {
			var ct = CommodityTypeCart{
				Type:              c.Type,
				Name:              c.TypeName,
			}

			var cc = CommodityCart{
				Commodity: c,
				Number:    1,
			}
			ct.CommodityCartList = append(ct.CommodityCartList, &cc)

			commodityTypeList = append(commodityTypeList, &ct)
		}
	}

	commodity.AddUsercommodity(commodityTypeList, uId)

	commodityTypeListStr, _ := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&commodityTypeList)

	ierr := rdb.Set("user_shopping_card_"+strconv.FormatInt(uId, 10), string(commodityTypeListStr), 0).Err()
	if ierr != nil {
		fmt.Printf("set departmentList failed, err:%v\n", ierr)
	}

	return commodityTypeList, nil
}

func (commodity *Commodity)QueryUserShoppingCardCache(uId string)([]*CommodityTypeCart, error){

	commodityTypeListStr, qerr := rdb.Get("user_shopping_card_"+uId).Result()
	if qerr != nil {
		fmt.Printf("get departmentList failed, err:%v\n", qerr)
		return nil, qerr
	}

	var commodityTypeList []*CommodityTypeCart
	jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(commodityTypeListStr), &commodityTypeList)

	return commodityTypeList, nil
}

func (commodity *Commodity)Close(commodityTypeList []*CommodityTypeCart, cList []*Coupon)(float64, error){

	var sum float64
	for _, t := range commodityTypeList {
		for _, commodity := range t.CommodityCartList {
			sum += commodity.Commodity.Money * float64(commodity.Number)
		}

		for _, c := range cList {
			sum -= c.Deduction
		}
	}
	return sum, nil
}

func (commodity *Commodity)AddUsercommodity(commodityTypeList []*CommodityTypeCart, uId int64){

	w := new(utils.Worker)

	for _, t := range commodityTypeList {
		for _, commodity := range t.CommodityCartList {
			var uc UserCommodity
			x.Where("user_id = ?", uId).And("commodity_id = ?", commodity.Commodity.Id).Get(&uc)
			if uc.Id != 0{
				uc.Number += commodity.Number
				x.Id(uc.Id).Update(&uc)
			}else {
				var newUc = UserCommodity{
					Id:          w.GetId(),
					UserId:      uId,
					CommodityId: commodity.Commodity.Id,
					CommodityName: commodity.Commodity.Name,
					Number:      commodity.Number,
					CreatedAt:   time.Now(),
					UpdatedAt:   time.Now(),
				}
				x.Insert(&newUc)
			}
		}
	}
}




